package cate.game.activity.lostdreamland;

import cate.common.table.activity.lostdreamland.row.LostDreamlandBaseRow;
import cate.common.table.activity.lostdreamland.row.LostDreamlandRewardRow;
import cate.common.table.d.GDFight;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDPosition;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleFarmActivitySingle;
import cate.game.activity.lostdreamland.msg.LostDreamlandDataResp;
import cate.game.activity.lostdreamland.msg.LostDreamlandRecordResp;
import cate.game.activity.lostdreamland.po.LostDreamlandLevel;
import cate.game.activity.lostdreamland.po.LostDreamlandRecord;
import cate.game.play.part.FightSide;
import cate.game.play.part.PlaySide;
import cate.game.play.proce.play.PlayPO;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

@NoteClass("迷失幻境活动")
public class LostDreamlandActivity extends RoleFarmActivitySingle {
    @JsonIgnore
    @NoteField(value = "活动当前天数")
    public int day;
    @NoteField(value = "各层数据")
    public Map<Integer, LostDreamlandLevel> levels;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (levels == null) {
            levels = new HashMap<>();
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        if (enable()){
            resetLevel();
            noticeUpdate();
        }
    }

    private void resetLevel() {
        if (!enable()) {
            return;
        }
        //活动当前天数
        int dayNow = getCurrentDay();
        if (levels.isEmpty()) {
            this.day = 0;
        }
        if (dayNow > this.day) {
            levels.clear();
            this.day = dayNow;
            for (LostDreamlandRewardRow row : role.getGame().table.lostDreamland.reward.getList()) {
                if (row.day == this.day && row.group == getRow().group) {
                    LostDreamlandLevel level = new LostDreamlandLevel();
                    level.initLevel(row);
                    levels.put(row.id, level);
                }
            }
        }
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        day = 0;
        levels.clear();
        fighting = false;
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        resetLevel();
    }

    @Override
    public int getFightFuncId() {
        return base.funcId;
    }

    public void noticeUpdate() {
        role.sendNow(new LostDreamlandDataResp(this));
    }

    public EcResult<Void> challenge(int level) {
        EcResult<Void> r = new EcResult<>();
        if (!enable()) {
            return r.fail("活动未开启");
        }
        if (isFighting()) {
            return r.fail("当前战斗未结束");
        }
        LostDreamlandLevel ldLevel = levels.get(level);
        if (ldLevel == null) {
            return r.fail("所选层数不存在");
        }
        if (ldLevel.passed) {
            return r.fail("所选关卡已通过");
        }
        r = doChallenge(level);
        if (r.ok()) {
            noticeUpdate();
            role.getHistory().action.challengeLostDreamLand();
        }
        return r;
    }

    public EcResult<Void> doChallenge(int level) {
        EcResult<Void> r = new EcResult<>();
        LostDreamlandRewardRow tpl = getLevelRow(level);
        if (tpl == null) {
            return r.fail("所选层数不存在1");
        }
        EcResult<PlaySide> psA_r = role.getGame().fight.side.createPlaySideByRole(role, getFightFuncId(), GDPosition.DEFAULT_POS_NUM);
        if (!psA_r.ok()) {
            return r.fail(psA_r.message);
        }
        FightSide fsA = role.getGame().fight.side.createFightSideByPlaySide(GDFight.Team.A, psA_r.data);
        EcResult<FightSide> fsOppo = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, tpl.instanceConfig);
        if (!fsOppo.ok()) {
            return r.fail(fsOppo.message);
        }
        LostDreamlandFTC context = new LostDreamlandFTC(role, getFightFuncId(), tpl);
        context.funcId = getFightFuncId();
        context.playStory.level = tpl.id;
        EcResult<PlayPO> fightRes = role.getGame().play.startByRole(role, context, fsA, fsOppo.data);
        if (!fightRes.ok()) {
            return r.fail(fightRes.message);
        }
        this.startFighting();
        return r;
    }


    @JsonIgnore
    public LostDreamlandBaseRow getRow() {
        return getRole().getGame().table.lostDreamland.base.get(base.configTid);
    }

    @JsonIgnore
    private LostDreamlandRewardRow getLevelRow(int id) {
        return role.getGame().table.lostDreamland.reward.get(id);
    }

    /**
     * 获胜后发放免费奖励
     */
    public void provideReward(int rowId) {
        LostDreamlandRewardRow row = getLevelRow(rowId);
        LostDreamlandLevel levelObj = levels.get(rowId);
        if (row != null) {
            MixRes rewardRes = new MixRes(row.freeReward);
            if (this.day == row.day && levelObj != null && !levelObj.passed) {
                levelObj.passed = true;
                if (rewardRes.isEmpty()) {
                    return;
                }
                //EcResult<?> exe = new MixResAdder().setRes(rewardRes)
                //       .setOperation(GDOperation.LOST_DREAMLAND)
                //       .setOperationSub(row.id)
                //       .setDialogReward(true)
                //        .setSendMailWhenFull(true)
                //        .exe(role);
                rewardRes.add(role, true, GDOperation.LOST_DREAMLAND);
                levelObj.freeGot = true;
            }
        }
    }

    /**
     * 购买追加奖励
     * @param role
     * @param tid
     * @param dialog
     */
    protected void provideBuyReward(Role role, int tid, boolean dialog) {
        LostDreamlandRewardRow row = getLevelRow(tid);
        LostDreamlandLevel levelObj = levels.get(tid);
        if (row == null) {
            return ;
        }
        MixRes rewardRes = new MixRes(row.buyReward);
        if (rewardRes.isEmpty()) {
            return ;
        }
        EcResult<?> exe = new MixResAdder().setRes(rewardRes)
                .setOperation(GDOperation.LOST_DREAMLAND)
                .setOperationSub(tid)
                .setDialogReward(dialog)
                .setSendMailWhenFull(true)
                .exe(role);
        levelObj.limit --;
        if (levelObj.limit == 0) {
            levelObj.buyGot = true;
        }
        noticeUpdate();
    }
    @Override
    public void onPaySuccess(PayItemRow payItemRow) {
        provideBuyReward(role, payItemRow.funcSubId, true);
    }

    /**
     * 支付条件
     * @param pir 支付配置
     * @return
     */
    @Override
    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        int tid = pir.funcSubId;
        if (!levels.containsKey(tid)) {
            return r.fail("该层数不存在");
        }
        LostDreamlandRewardRow row = getLevelRow(tid);
        if (row == null) {
            return r.fail("未找到配置");
        }
        if (levels.get(tid).buyGot) {
            return r.fail("不可重复购买");
        }
        if (!levels.get(tid).passed) {
            return r.fail("未击败不可购买");
        }
        MixRes rewardRes = new MixRes(row.buyReward);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        return r.success();
    }

    public EcResult<Void> getRecord(int level) {
        EcResult<Void> r = new EcResult<>();
        if (!enable()) {
            return r.fail("活动已结束");
        }
        LostDreamlandHandler handler = role.getGame().activityGlobal.getHandler(funcId());
        if (handler == null) {
            return r.fail("活动已结束");
        }
        LostDreamlandLevel levelObj = levels.get(level);
        LostDreamlandRewardRow levelRow = getLevelRow(level);
        if (levelRow == null) {
            return r.fail("所选关卡不存在");
        }
        LostDreamlandRecord record = handler.getRecord(base.activityId, this.day, levelObj.level);
        role.sendNow(new LostDreamlandRecordResp(funcId(), record));
        return r;
    }
}
